const axios = require('axios');
const cheerio = require('cheerio');

class RequirementAnalysisService {
  constructor() {
    // 默认的 Confluence 认证信息
    this.auth = {
      username: 'gushan',
      password: '123456' // 注意：实际可以从前端传过来，这里作为默认值或者fallback
    };
  }

  async fetchAndParse(url, username, password) {
    try {
      // 1. 获取页面内容
      const auth = {
        username: username || this.auth.username,
        password: password || this.auth.password
      };
      
      const response = await axios.get(url, {
        auth: auth,
        headers: {
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
        }
      });

      const html = response.data;
      const $ = cheerio.load(html);
      
      // 2. 解析页面信息
      const pageTitle = $('#title-text').text().trim() || $('title').text().trim();
      
      console.log('=== 调试信息 ===');
      console.log('页面标题:', pageTitle);
      
      // 3. 解析各个主要区域（Expander）
      const sections = [];
      
      // 查找所有的扩展控制器
      $('.expand-control').each((i, elem) => {
        const $control = $(elem);
        const title = $control.find('.expand-control-text').text().trim();
        
        // title 包含相关关键字的才解析
        const keywords = ['列表栏位', '查询条件', '字段说明', '说明'];
        if (!keywords.some(keyword => title.includes(keyword))) {
          return;
        }

        const controlId = $control.attr('id');
        if (!controlId) return;
        
        const contentId = controlId.replace('control', 'content');
        const $content = $(`#${contentId}`);
        
        if ($content.length > 0) {
          console.log(`解析区域: ${title}`);
          const sectionData = this.parseSection($, $content, title);
          if (sectionData) {
            sections.push(sectionData);
          }
        }
      });
      
      console.log(`总计解析区域数量: ${sections.length}`);

      // 4. 结构化重组
      const dynamicStructure = {};
      const areaMapping = {
        '列表': 'header',
        '表头': 'header',
        '表体': 'body',
      };
      
      // 区域代码辅助函数
      const getAreaCode = (name) => {
        for (const [key, val] of Object.entries(areaMapping)) {
            if (name === key) return val;
        }
        return `body_${name}`
      };

      // ------------------------------------------------------
      // 第一步：根据“查询区域说明”和“列表栏位说明”确认区域 (Identify Areas)
      // ------------------------------------------------------    
      if ((sections[0] && sections[0].headers.length > 0) || sections[1] && sections[1].headers.length > 0) {
        const headerKeys = [...sections[0].headers, ...sections[1].headers];
        
        // 识别 【XX】页 或类似格式的列名来确定区域
        const titleRegex = /【(.*?)】/;
        const detectedAreas = new Set();

        headerKeys.forEach(h => {
            const match = h.match(titleRegex);
            if (match) {
                const areaName = match[1];
                const areaCode = getAreaCode(areaName);
                
                if (!dynamicStructure[areaCode]) {
                    dynamicStructure[areaCode] = { 
                        name: areaName, 
                        search: [], 
                        table: [], 
                        form: [] 
                    };
                    detectedAreas.add(areaCode);
                    console.log(`检测到区域: ${areaCode} (${areaName})`);
                }
            }
        });

        // 如果未能自动检测到（旧格式或无特定列），默认使用 header
        if (Object.keys(dynamicStructure).length === 0) {
             dynamicStructure['header'] = { name: '列表', search: [], table: [], form: [] };
             console.log(`未检测到明确区域，使用默认 header`);
        }

        // ------------------------------------------------------
        // 第二步：分发“查询字段” (Distribute Search Fields)
        // ------------------------------------------------------
        sections[0].fields.forEach(field => {
            Object.keys(dynamicStructure).forEach(areaCode => {
                const areaKeywords = areaCode === 'header' ? ['列表', '表头'] : [dynamicStructure[areaCode].name];
                
                // 查找属于该区域的配置列和默认显示列
                // 匹配逻辑：列名包含 【区域关键字】 且 (包含 '配置' 或 '查询')
                const configCol = Object.keys(field.raw).find(k => 
                    areaKeywords.some(kw => k.includes(`【${kw}】`)) && (k.includes('配置') || k.includes('查询条件') || k.includes('栏位'))
                );
                const showCol = Object.keys(field.raw).find(k => 
                    areaKeywords.some(kw => k.includes(`【${kw}】`)) && (k.includes('默认') || k.includes('显示'))
                );
                
                // 如果在该区域的配置列中有值，则认为该字段属于该区域的查询条件
                if (configCol && this.isVisible(field.raw[configCol])) {
                     const searchField = { 
                         ...field, 
                         isDefaultShow: showCol ? this.isTrue(field.raw[showCol]) : false
                     };
                     dynamicStructure[areaCode].search.push(searchField);
                }
            });
        });
      } else {
        // 兜底：如果没有查询区域说明，创建一个默认 header 区域
        if (Object.keys(dynamicStructure).length === 0) {
            dynamicStructure['header'] = { name: '列表', search: [], table: [], form: [] };
        }
      }

      // ------------------------------------------------------
      // 第三步：分发“列表字段” (Distribute Table Fields)
      // ------------------------------------------------------

      sections[1].fields.forEach(field => {
            Object.keys(dynamicStructure).forEach(areaCode => {
              const areaKeywords = areaCode === 'header' ? ['列表', '表头'] : [dynamicStructure[areaCode].name];
              
              const configCol = Object.keys(field.raw).find(k => 
                  areaKeywords.some(kw => k.includes(`【${kw}】`)) && (k.includes('配置') || k.includes('栏位'))
              );
              const showCol = Object.keys(field.raw).find(k => 
                  areaKeywords.some(kw => k.includes(`【${kw}】`)) && (k.includes('默认') || k.includes('显示'))
              );
              
              if (configCol) {
                  // 如果有明确的区域列配置
                  if (this.isVisible(field.raw[configCol])) {
                      const tableField = { 
                          ...field, 
                          isDefaultShow: showCol ? this.isTrue(field.raw[showCol]) : false
                      };
                      dynamicStructure[areaCode].table.push(tableField);
                  }
              }
            });
      });


      // ------------------------------------------------------
      // 第四步：分发“表单字段” (Distribute Form Fields)
      // ------------------------------------------------------
      sections.forEach((sec, index) => {
        // 跳过查询和列表说明区域
        if (index === 0 || index === 1) return;

        // 按照dynamicStructure 的 name判断区域归属，进行分发，表体如果存在多个，如 name=表体，单损耗
        // sec.title 优先匹配单损耗，如果匹配不到，再按照表体匹配

        let targetAreaCode = ''
        Object.keys(dynamicStructure).filter(areaCode => areaCode !== 'body').some(areaCode => { 
          const firstName = dynamicStructure[areaCode].name
          if (sec.title.includes(firstName)) {
            targetAreaCode = areaCode;
            return true;
          }
          // 如果firstName 包含 -或_, 则按照分隔符分割，取第一个进行尝试匹配
          const separators = ['-', '_'];
          for (const separator of separators) {
            const parts = firstName.split(separator);
            if (parts.length > 1 && sec.title.includes(parts[1])) {
              targetAreaCode = areaCode;
              return true;
            }
          }
        });

        if (!targetAreaCode) {
          if (sec.title.includes('表体')) {
            targetAreaCode = 'body';
          } else if (sec.title.includes('表头')) {
            targetAreaCode = 'header';
          }
        }
        
        // 仅处理包含 '字段' 或 '表头'/'表体' 的说明区域
        if (!sec.title.includes('说明') && !sec.title.includes('字段')) return;

        // 只有当该区域在 dynamicStructure 中存在时才添加 (严格遵循"根据查询区域说明确认"的原则)
        // 特例：如果查询区域没定义 body，但这里有表体说明，是否要加？
        // 按照用户指令 "对应区域的表单字段均来自页面字段说明"，暗示如果没有对应区域，就不应该有字段。
        if (targetAreaCode && dynamicStructure[targetAreaCode]) {
            dynamicStructure[targetAreaCode].form.push(...sec.fields);
            console.log(`表单字段区域 ${sec.title} 分发到 ${targetAreaCode}`);
        }
      });

      console.log('=== 结构化重组完成 ===');

      return {
        pageTitle,
        url,
        sections, 
        structure: dynamicStructure 
      };

    } catch (error) {
      console.error('Fetch and parse error:', error.message);
      throw new Error(`解析失败: ${error.message}`);
    }
  }

  isVisible(val) {
    if (!val) return false;
    const s = String(val).trim().toLowerCase();
    return s.length > 0 && !(s === '否' || s === 'false' || s === 'no' || s === '-' || s === '/');
  }

  isTrue(val) {
    if (!val) return false;
    const s = String(val).trim().toLowerCase();
    return s.includes('是') || s.includes('true') || s.includes('yes') || s.includes('√') || s.includes('checked');
  }

  parseSection($, $content, title) {
    const table = $content.find('table.confluenceTable').first();
    if (table.length === 0) return null;

    // --- 解析多级表头 (Matrix Strategy) ---
    let headers = [];
    let dataStartRowIndex = 0;
    
    const theadRows = table.find('thead tr');
    
    const tbodyRows = table.children('tbody').children('tr');

    
    if (theadRows.length > 0) {
      const grid = [];
      let maxCols = 0;
      
      theadRows.each((r, tr) => {
        if (!grid[r]) grid[r] = [];
        const cells = $(tr).find('th, td');
        let currentC = 0;
        
        cells.each((i, cell) => {
          const $cell = $(cell);
          const colspan = parseInt($cell.attr('colspan') || '1', 10);
          const rowspan = parseInt($cell.attr('rowspan') || '1', 10);
          const text = $cell.text().replace(/\s+/g, '');
          
          while (grid[r][currentC]) currentC++;
          
          for (let rr = 0; rr < rowspan; rr++) {
            if (!grid[r + rr]) grid[r + rr] = [];
            for (let cc = 0; cc < colspan; cc++) {
              grid[r + rr][currentC + cc] = text;
            }
          }
          maxCols = Math.max(maxCols, currentC + colspan);
        });
      });

      for (let c = 0; c < maxCols; c++) {
        let headerText = '';
        const seen = new Set(); 
        for (let r = 0; r < grid.length; r++) {
          const cellText = grid[r][c];
          if (cellText && !seen.has(cellText)) {
            headerText += cellText;
            seen.add(cellText);
          }
        }
        headers.push(headerText);
      }
      dataStartRowIndex = 0; 
    } else {
      // 无 thead，尝试从 tbody 第一行提取
      const firstTr = tbodyRows.first();
      dataStartRowIndex = 1;
      firstTr.find('th, td').each((i, cell) => {
        if (cell.attribs.colspan && parseInt(cell.attribs.colspan) > 1) {
          dataStartRowIndex = 2;
          const colSpan = parseInt(cell.attribs.colspan);
          tbodyRows.eq(1).find('th, td').each((i, subCell) => {
            if (i < colSpan) {
              headers.push($(cell).text().replace(/\s+/g, '')+'_'+ $(subCell).text().replace(/\s+/g, '') );
            }
          });
        } else {
          headers.push($(cell).text().replace(/\s+/g, ''));
        }
      });
    }
    console.log(`表头解析完成: ${headers}`);
    // --- 解析数据行 ---
    const rows = [];
    const bodyGrid = [];
    
    tbodyRows.each((r, tr) => {
      if (!bodyGrid[r]) bodyGrid[r] = [];
      // 取第一层的td,th
      const cells = $(tr).children().filter(function() { return $(this).is('th, td'); });
      let currentC = 0;
      
      cells.each((i, cell) => {
        const $cell = $(cell);
        const colspan = parseInt($cell.attr('colspan') || 1, 10);
        const rowspan = parseInt($cell.attr('colspan') || 1, 10);
        const text = $cell.text().trim();
        
        while (bodyGrid[r][currentC] !== undefined) currentC++;
        
        for (let rr = 0; rr < 1; rr++) {
          const targetRow = r + rr;
          if (!bodyGrid[targetRow]) bodyGrid[targetRow] = [];
          for (let cc = 0; cc < 1; cc++) {
            bodyGrid[targetRow][currentC + cc] = text;
          }
        }
        currentC += colspan;
      });
    });

    // 映射数据
    for (let i = dataStartRowIndex; i < bodyGrid.length; i++) {
      const rowCells = bodyGrid[i] || [];
      if (rowCells.length === 0) continue;

      const rowData = {};
      headers.forEach((h, colIndex) => {
         if (h && rowCells[colIndex]) {
            rowData[h] = rowCells[colIndex];
         }
      });

      if (Object.keys(rowData).length > 0) {
        rows.push(rowData);
      }
    }

    // --- 识别字段属性 ---
    const keys = rows[0] ? Object.keys(rows[0]) : [];
    
    const labelKey = keys.find(k => k.includes('名称') || k.includes('字段') || k.toLowerCase() === 'label' || k.includes('栏位') || k.includes('汇总'));
    const requiredKey = keys.find(k => k.includes('必填') || k.includes('是否必要'));
    const typeKey = keys.find(k => k.includes('类型') || k.includes('方式') || k.includes('组件'));
    const descKey = keys.find(k => k.includes('说明') || k.includes('校验') || k.includes('描述'));

    const fields = rows.map(row => {
      if (!labelKey || !row[labelKey]) return null; // 过滤无效行

      const label = row[labelKey];
      // 如果 label 包含 页面不显示，则忽略
      if (label.includes('页面不显示')) return null;

      const fieldData = {
        raw: row, 
        label: label, 
        fieldName: '', 
        required: requiredKey ? (row[requiredKey] && row[requiredKey].includes('必填')) : false,
        componentType: this.guessComponentType(typeKey ? row[typeKey] + label: label),
        description: descKey ? row[descKey] : '',
      };
      return fieldData;
    }).filter(f => f);

    // 简单的分组（不再依赖内部逻辑判断，而是交由 fetchAndParse 处理）
    return {
      title,
      headers, 
      fields,
      groups: {} 
    };
  }

  guessComponentType(text) {
    if (!text) return 'Input';
    if (text.includes('日期') || text.includes('时间')) return 'DatePicker';
    if (text.includes('下拉') || text.includes('选择')) return 'Select';
    if (text.includes('数字') || text.includes('金额')) return 'InputNumber';
    if (text.includes('文本域')  || text.includes('多行')) return 'Textarea';
    return 'Input';
  }
}

module.exports = new RequirementAnalysisService();
